/*
 * 描述： <描述>
 * 修改人： rain
 * 修改时间： 2016年1月24日
 * 项目： rainhy-cores-webcore
 */
package com.rainhy.webcore.holder;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;

/**
 * SpringContext Holder
 * 
 * @author rain
 * @version [版本号, 2016年1月24日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
@Component("rainhy.webcore.SpringContextHolder")
public class SpringContextHolder implements ApplicationEventPublisherAware, ApplicationContextAware, InitializingBean, FactoryBean<SpringContextHolder> {
    
    /** 日志 */
    private static final Logger logger = LoggerFactory.getLogger(SpringContextHolder.class);
    
    /** 自身唯一引用 */
    private static SpringContextHolder holder;
    
    /** 返回自身唯一引用 */
    public static SpringContextHolder get() {
        return SpringContextHolder.holder;
    }
    
    /** 根据 bean type 获取 bean */
    public static <T> T getBean(Class<T> beanType) throws BeansException {
        return SpringContextHolder.get().getApplicationContext().getBean(beanType);
    }
    
    /** 根据 bean name 获取 bean */
    public static Object getBean(String name) throws BeansException {
        return SpringContextHolder.get().getApplicationContext().getBean(name);
    }
    
    /** 根据 bean name 和 bean type 获取 bean */
    public static <T> T getBean(String name, Class<T> beanType) throws BeansException {
        return SpringContextHolder.get().getApplicationContext().getBean(name, beanType);
    }
    
    /** 推送发布事件 */
    public static void publishEvent(ApplicationEvent event) {
        SpringContextHolder.get().getApplicationEventPublisher().publishEvent(event);
    }
    
    /** 推送发布事件 */
    public static void publishEvent(Object event) {
        SpringContextHolder.get().getApplicationEventPublisher().publishEvent(event);
    }
    
    /** spring事件发布者 */
    private ApplicationEventPublisher applicationEventPublisher;
    
    /** spring 容器 */
    private ApplicationContext applicationContext;
    
    @Override
    public void afterPropertiesSet() throws Exception {
        SpringContextHolder.holder = this;
        logger.info("加载[SpringContext Holder]...");
    }
    
    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }
    
    /** @return 返回 applicationEventPublisher */
    public ApplicationEventPublisher getApplicationEventPublisher() {
        return applicationEventPublisher;
    }
    
    @Override
    public SpringContextHolder getObject() throws Exception {
        return SpringContextHolder.get();
    }
    
    @Override
    public Class<?> getObjectType() {
        return SpringContextHolder.class;
    }
    
    @Override
    public boolean isSingleton() {
        return true;
    }
    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
    
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }
}
